<template>
  <div class="data-source-container">
    <div class="toolbar">
      <div class="left">
        <el-button type="primary" @click="handleCreate">
          <el-icon><Plus /></el-icon>新建数据源
        </el-button>
        <el-radio-group v-model="viewMode" class="view-mode">
          <el-radio-button label="table">
            <el-icon><List /></el-icon>
          </el-radio-button>
          <el-radio-button label="card">
            <el-icon><Grid /></el-icon>
          </el-radio-button>
        </el-radio-group>
      </div>
      <el-input
        v-model="searchQuery"
        placeholder="搜索数据源名称"
        class="search-input"
      >
        <template #prefix>
          <el-icon><Search /></el-icon>
        </template>
      </el-input>
    </div>

    <!-- 表格视图 -->
    <el-table
      v-if="viewMode === 'table'"
      :data="dataSourceList"
      style="width: 100%"
      v-loading="loading"
    >
      <el-table-column prop="name" label="数据源名称" min-width="150" />
      <el-table-column prop="type" label="类型" width="120" />
      <el-table-column prop="host" label="主机地址" min-width="150" />
      <el-table-column prop="port" label="端口" width="100" />
      <el-table-column prop="database" label="数据库" min-width="150" />
      <el-table-column prop="status" label="状态" width="100">
        <template #default="{ row }">
          <el-tag
            :type="
              row.status === DataSourceStatus.Connected ? 'success' : 'info'
            "
          >
            {{
              row.status === DataSourceStatus.Connected ? "已连接" : "未连接"
            }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="250">
        <template #default="{ row }">
          <el-button-group>
            <el-button
              type="primary"
              link
              :loading="row.testing"
              @click="handleTest(row)"
            >
              测试连接
            </el-button>
            <el-button type="primary" link @click="handleEdit(row)">
              编辑
            </el-button>
            <el-button type="danger" link @click="handleDelete(row)">
              删除
            </el-button>
          </el-button-group>
        </template>
      </el-table-column>
    </el-table>

    <!-- 卡片视图 -->
    <draggable
      v-if="viewMode === 'card'"
      v-model="dataSourceList"
      class="card-view"
      v-loading="loading"
      :group="{ name: 'datasources' }"
      item-key="id"
      handle=".drag-handle"
      @end="handleDragEnd"
    >
      <template #item="{ element: item }">
        <el-card class="data-source-card" :body-style="{ padding: '20px' }">
          <div class="card-header">
            <div class="card-title">
              <el-icon class="drag-handle"><Rank /></el-icon>
              <span class="name">{{ item.name }}</span>
              <el-tag :type="getStatusTagType(item.status)" size="small">
                {{ getStatusText(item.status) }}
              </el-tag>
            </div>
            <div class="card-type">
              <el-tag effect="plain">{{ item.type }}</el-tag>
            </div>
          </div>
          <div class="card-content">
            <div class="info-item">
              <span class="label">主机地址：</span>
              <span class="value">{{ item.host }}</span>
            </div>
            <div class="info-item">
              <span class="label">端口：</span>
              <span class="value">{{ item.port }}</span>
            </div>
            <div class="info-item">
              <span class="label">数据库：</span>
              <span class="value">{{ item.database }}</span>
            </div>
          </div>
          <div class="card-footer">
            <el-button-group>
              <el-button
                type="primary"
                :loading="item.testing"
                @click="handleTest(item)"
                size="small"
              >
                测试连接
              </el-button>
              <el-button type="primary" @click="handleEdit(item)" size="small">
                编辑
              </el-button>
              <el-button type="danger" @click="handleDelete(item)" size="small">
                删除
              </el-button>
            </el-button-group>
          </div>
        </el-card>
      </template>
    </draggable>

    <div class="pagination">
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :total="total"
        :page-sizes="[10, 20, 50, 100]"
        layout="total, sizes, prev, pager, next"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <el-dialog
      :title="editingData ? '编辑数据源' : '新建数据源'"
      v-model="dialogVisible"
      width="500px"
    >
      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
        <el-form-item label="数据源名称" prop="name">
          <el-input v-model="form.name" />
        </el-form-item>
        <el-form-item label="数据库类型" prop="type">
          <el-select v-model="form.type" placeholder="请选择数据库类型">
            <el-option
              v-for="type in Object.values(DataSourceType)"
              :key="type"
              :label="type"
              :value="type"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="主机地址" prop="host">
          <el-input v-model="form.host" />
        </el-form-item>
        <el-form-item label="端口" prop="port">
          <el-input-number v-model="form.port" :min="1" :max="65535" />
        </el-form-item>
        <el-form-item label="数据库名" prop="database">
          <el-input v-model="form.database" />
        </el-form-item>
        <el-form-item label="用户名" prop="username">
          <el-input v-model="form.username" />
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input v-model="form.password" type="password" show-password />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button
            type="primary"
            plain
            :loading="testingConnection"
            @click="handleTestFormConnection"
          >
            测试连接
          </el-button>
          <el-button type="primary" :loading="submitting" @click="handleSubmit">
            确定
          </el-button>
        </div>
      </template>
    </el-dialog>

    <DataSourceTables
      v-model:visible="tablesVisible"
      :data-source="currentDataSource as DataSource"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, watch, onMounted, reactive } from "vue";
import { Plus, Search, List, Grid, Rank } from "@element-plus/icons-vue";
import { ElMessage, ElMessageBox } from "element-plus";
import Draggable from "vuedraggable";
import type { FormInstance } from "element-plus";
import DataSourceForm from "./components/DataSourceForm.vue";
import DataSourceTables from "./components/DataSourceTables.vue";
import {
  getDataSourceList,
  createDataSource,
  updateDataSource,
  deleteDataSource,
  testDataSourceConnection,
  testConnectionWithConfig,
} from "@/api/dataSource";
import type { DataSource } from "@/types/dataSource";
import { DataSourceType, DataSourceStatus } from "@/constants/dataSource";

console.log("数据源管理页面组件开始初始化");

const loading = ref(false);
const initialized = ref(false);
const searchQuery = ref("");
const currentPage = ref(1);
const pageSize = ref(10);
const total = ref(0);
const dialogVisible = ref(false);
const dataSourceList = ref<DataSource[]>([]);
const editingData = ref<DataSource | null>(null);
const formRef = ref<FormInstance>();
const viewMode = ref<"table" | "card">("table");
const tablesVisible = ref(false);
const currentDataSource = ref<DataSource | null>(null);
const submitting = ref(false);
const testingConnection = ref(false);

const form = reactive({
  name: "",
  type: "",
  host: "",
  port: 3306,
  database: "",
  username: "",
  password: "",
});

const rules = {
  name: [{ required: true, message: "请输入数据源名称", trigger: "blur" }],
  type: [{ required: true, message: "请选择数据库类型", trigger: "change" }],
  host: [{ required: true, message: "请输入主机地址", trigger: "blur" }],
  port: [{ required: true, message: "请输入端口", trigger: "blur" }],
  database: [{ required: true, message: "请输入数据库名", trigger: "blur" }],
  username: [{ required: true, message: "请输入用户名", trigger: "blur" }],
  password: [{ required: true, message: "请输入密码", trigger: "blur" }],
};

const getStatusTagType = (status: DataSourceStatus) => {
  const types: Record<DataSourceStatus, string> = {
    [DataSourceStatus.Connected]: "success",
    [DataSourceStatus.Disconnected]: "info",
    [DataSourceStatus.Error]: "danger",
  };
  return types[status];
};

const getStatusText = (status: DataSourceStatus) => {
  const texts: Record<DataSourceStatus, string> = {
    [DataSourceStatus.Connected]: "已连接",
    [DataSourceStatus.Disconnected]: "未连接",
    [DataSourceStatus.Error]: "错误",
  };
  return texts[status];
};

// 新增: 数据源类型对应的默认端口
const defaultPorts: Record<DataSourceType, number> = {
  [DataSourceType.MySQL]: 3306,
  [DataSourceType.PostgreSQL]: 5432,
  [DataSourceType.SQLServer]: 1433,
  [DataSourceType.Oracle]: 1521,
  [DataSourceType.MongoDB]: 27017,
  [DataSourceType.Redis]: 6379,
  [DataSourceType.Elasticsearch]: 9200,
};

// 监听数据库类型的变化，自动设置对应的端口
watch(
  () => form.type,
  (newType) => {
    if (newType && defaultPorts[newType as DataSourceType]) {
      // 只有当用户没有手动修改过端口或当前是系统默认端口时才自动修改
      const currentPort = form.port;
      const isDefaultPort = Object.values(defaultPorts).includes(currentPort);

      if (!currentPort || isDefaultPort) {
        form.port = defaultPorts[newType as DataSourceType];
      }
    }
  }
);

const loadData = async () => {
  if (!initialized.value) {
    console.log("等待初始化完成...");
    setTimeout(loadData, 100);
    return;
  }

  loading.value = true;
  try {
    const params = {
      keyword: searchQuery.value,
      page: currentPage.value,
      pageSize: pageSize.value,
    };

    console.log("加载数据，参数:", params);

    // 获取响应数据
    const result = await getDataSourceList(params);
    console.log("获取到响应:", result);

    // 检查结果结构
    if (result && result.data) {
      // 数据在 result.data.data 中，而不是 result.data 中
      const { data } = result.data;
      if (data && data.list && data.total) {
        const { list, total: totalCount } = data;
        console.log("解析的数据:", { list, totalCount });

        // 处理数据，保持与现有代码一致
        if (Array.isArray(list)) {
          dataSourceList.value = list;
          total.value = totalCount;

          // 从 localStorage 获取排序信息
          const savedOrder = localStorage.getItem("dataSourceOrder");
          if (savedOrder) {
            try {
              const orderMap = JSON.parse(savedOrder);
              // 应用保存的排序
              dataSourceList.value.sort((a: DataSource, b: DataSource) => {
                const orderA = a.id
                  ? orderMap[a.id] ?? Number.MAX_SAFE_INTEGER
                  : Number.MAX_SAFE_INTEGER;
                const orderB = b.id
                  ? orderMap[b.id] ?? Number.MAX_SAFE_INTEGER
                  : Number.MAX_SAFE_INTEGER;
                return orderA - orderB;
              });
            } catch (e) {
              console.error("解析排序信息失败:", e);
            }
          }
        } else {
          console.error("API返回的列表格式不正确:", list);
          dataSourceList.value = [];
          total.value = 0;
        }
      } else {
        console.error("API返回的数据结构不正确:", result.data);
        dataSourceList.value = [];
        total.value = 0;
      }
    } else {
      console.error("API返回格式不正确:", result);
      dataSourceList.value = [];
      total.value = 0;
    }
  } catch (error) {
    console.error("加载数据源列表失败:", error);
    ElMessage.error("加载数据源列表失败，请刷新重试");
    dataSourceList.value = [];
    total.value = 0;
  } finally {
    loading.value = false;
  }
};

const resetForm = () => {
  if (formRef.value) {
    formRef.value.resetFields();
  }
  Object.assign(form, {
    name: "",
    type: "",
    host: "",
    port: 3306,
    database: "",
    username: "",
    password: "",
  });
};

const handleCreate = () => {
  editingData.value = null;
  resetForm();
  dialogVisible.value = true;
};

const handleEdit = (row: DataSource) => {
  editingData.value = row;
  Object.assign(form, row);
  dialogVisible.value = true;
};

const handleTest = async (row: DataSource) => {
  if (!row.id) return;

  // 使用类型断言确保正确的类型
  const testingIndex = dataSourceList.value.findIndex(
    (item: DataSource) => item.id === row.id
  );
  if (testingIndex === -1) return;

  // 设置测试状态
  dataSourceList.value[testingIndex] = {
    ...dataSourceList.value[testingIndex],
    testing: true,
  };

  try {
    const result = await testDataSourceConnection(row.id);

    // 获取最新的行数据（可能在测试期间被修改）
    const currentIndex = dataSourceList.value.findIndex(
      (item) => item.id === row.id
    );
    if (currentIndex === -1) return;

    if (result.success) {
      ElMessage.success("连接成功");
      // 更新状态
      dataSourceList.value[currentIndex] = {
        ...dataSourceList.value[currentIndex],
        status: DataSourceStatus.Connected,
        testing: false,
      };
    } else {
      ElMessage.error(`连接失败: ${result.message}`);
      // 更新状态
      dataSourceList.value[currentIndex] = {
        ...dataSourceList.value[currentIndex],
        status: DataSourceStatus.Error,
        testing: false,
      };
    }
  } catch (error) {
    ElMessage.error("测试连接失败");
    console.error("测试连接失败:", error);

    // 获取最新的行数据
    const currentIndex = dataSourceList.value.findIndex(
      (item) => item.id === row.id
    );
    if (currentIndex === -1) return;

    // 更新状态
    dataSourceList.value[currentIndex] = {
      ...dataSourceList.value[currentIndex],
      status: DataSourceStatus.Error,
      testing: false,
    };
  }
};

const handleDelete = (row: DataSource) => {
  if (!row.id) return;

  ElMessageBox.confirm("确定要删除该数据源吗？", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(async () => {
    loading.value = true;
    try {
      await deleteDataSource(row.id);
      ElMessage.success("删除成功");
      loadData();
    } finally {
      loading.value = false;
    }
  });
};

const handleSubmit = async () => {
  if (!formRef.value) return;

  await formRef.value.validate(async (valid: boolean) => {
    if (valid) {
      try {
        submitting.value = true;

        if (editingData.value) {
          // 更新
          const result = await updateDataSource(editingData.value.id, form);
          if (result.data.code === 0) {
            ElMessage.success("更新成功");
            dialogVisible.value = false;
            await loadData();
            emitDataSourceChanged();
          } else {
            ElMessage.error(result.data.message || "更新失败");
          }
        } else {
          // 创建
          const result = await createDataSource(form);
          if (result.data.code === 0) {
            ElMessage.success("创建成功");
            dialogVisible.value = false;
            await loadData();
            emitDataSourceChanged();
          } else {
            ElMessage.error(result.data.message || "创建失败");
          }
        }
      } catch (error) {
        console.error("保存失败:", error);
        ElMessage.error("操作失败，请重试");
      } finally {
        submitting.value = false;
      }
    }
  });
};

const handleSizeChange = (val: number) => {
  pageSize.value = val;
  loadData();
};

const handleCurrentChange = (val: number) => {
  currentPage.value = val;
  loadData();
};

watch([searchQuery], () => {
  currentPage.value = 1;
  loadData();
});

// 保存视图模式到 localStorage
watch(viewMode, (newMode: "table" | "card") => {
  localStorage.setItem("dataSourceViewMode", newMode);
});

// 添加拖动排序相关的代码
const handleDragEnd = () => {
  // 保存新的排序到 localStorage
  const orderMap = dataSourceList.value.reduce(
    (acc: Record<number, number>, item: DataSource, index: number) => {
      if (item.id) {
        acc[item.id] = index;
      }
      return acc;
    },
    {} as Record<number, number>
  );

  localStorage.setItem("dataSourceOrder", JSON.stringify(orderMap));
};

// 初始化时从 localStorage 读取视图模式
onMounted(async () => {
  console.log("数据源管理页面组件已挂载");
  try {
    // 从 localStorage 获取视图模式
    const savedMode = localStorage.getItem("dataSourceViewMode");
    console.log("从 localStorage 读取的视图模式:", savedMode);

    if (savedMode === "table" || savedMode === "card") {
      viewMode.value = savedMode;
    }

    // 标记初始化完成
    initialized.value = true;
    console.log("初始化标记完成");

    // 加载数据
    console.log("开始加载数据...");
    await loadData();
    console.log("数据加载完成");
  } catch (error) {
    console.error("初始化失败:", error);
    ElMessage.error("页面初始化失败，请刷新重试");
  }
});

const handleViewTables = (row: DataSource) => {
  currentDataSource.value = row;
  tablesVisible.value = true;
};

const handleTestFormConnection = async () => {
  if (!formRef.value) return;

  await formRef.value.validate(async (valid: boolean) => {
    if (valid) {
      testingConnection.value = true;
      try {
        console.log("测试连接，表单数据:", form);

        if (editingData.value && editingData.value.id) {
          console.log("测试现有数据源, ID:", editingData.value.id);
          // 测试现有数据源
          const result = await testDataSourceConnection(editingData.value.id);
          if (result.success) {
            ElMessage.success("连接成功");
          } else {
            ElMessage.error(`连接失败: ${result.message || "请检查配置"}`);
          }
        } else {
          console.log("测试新数据源配置");
          // 使用表单值测试新数据源连接
          const result = await testConnectionWithConfig({
            type: form.type as DataSourceType,
            host: form.host,
            port: form.port,
            database: form.database,
            username: form.username,
            password: form.password,
          });

          if (result.success) {
            ElMessage.success("连接成功");
          } else {
            ElMessage.error(`连接失败: ${result.message || "请检查配置"}`);
          }
        }
      } catch (error) {
        console.error("测试连接失败:", error);
        ElMessage.error("测试连接失败，请检查配置");
      } finally {
        testingConnection.value = false;
      }
    } else {
      ElMessage.warning("请先完成表单的必填项");
    }
  });
};

// 在数据源保存成功后，发布一个自定义事件
const emitDataSourceChanged = () => {
  const event = new CustomEvent("datasource-changed");
  window.dispatchEvent(event);
};
</script>

<style scoped>
.data-source-container {
  padding: 20px;
}

.toolbar {
  margin-bottom: 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.toolbar .left {
  display: flex;
  align-items: center;
  gap: 16px;
}

.view-mode {
  margin-left: 16px;
}

.search-input {
  width: 300px;
}

.card-view {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 20px;
  margin-bottom: 20px;
}

.data-source-card {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 16px;
}

.card-title {
  display: flex;
  align-items: center;
  gap: 8px;
}

.card-title .name {
  font-size: 16px;
  font-weight: 500;
}

.card-content {
  flex: 1;
  margin-bottom: 16px;
}

.info-item {
  margin-bottom: 8px;
  display: flex;
  align-items: center;
}

.info-item .label {
  color: var(--el-text-color-secondary);
  width: 80px;
}

.info-item .value {
  color: var(--el-text-color-primary);
}

.card-footer {
  display: flex;
  justify-content: flex-end;
}

.pagination {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

.drag-handle {
  cursor: move;
  color: var(--el-text-color-secondary);
  margin-right: 8px;
}

.drag-handle:hover {
  color: var(--el-text-color-primary);
}

/* 拖动时的样式 */
.sortable-ghost {
  opacity: 0.5;
  background: var(--el-color-primary-light-9);
}

.sortable-drag {
  opacity: 0.9;
  background: var(--el-color-white);
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 12px;
}

/* 为测试按钮添加一些样式，使其与其他按钮区分开 */
.test-button {
  margin-right: auto; /* 把它放在左侧 */
}
</style> 